#include "sle_low_latency.h"
// #include "reDoor.h"

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "cmsis_os2.h"
#include "app_init.h"
#include "soc_osal.h"
#include "wifi_connect.h"

#include "common_def.h"
#include "pinctrl.h"
#include "uart.h"

#include "securec.h"
#include "sle_uart_server.h"
#include "sle_uart_server_adv.h"
#include "sle_device_discovery.h"
#include "sle_errcode.h"

#include "lwip/nettool/misc.h"
#include "lwip/ip4_addr.h"
#include "lwip/netif.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"

#include "watchdog.h"
#include "i2c.h"
#include "osal_debug.h"

#include "ssd1306_fonts.h"
#include "ssd1306.h"
#include "gpio.h"

#include "chinese_fonts.h"

#include "adc.h"
#include "adc_porting.h"

#include "sht3x.h"
#include "gps.h"
#define SLE_GATEWAY_TASK_DURATION_MS           2000
#define SLE_GATEWAY_TASK_PRIO                  28


#define I2C_MASTER_ADDR                   0x0
#define I2C_SET_BAUDRATE                  400000
#define I2C_MASTER_PIN_MODE               2

#define I2C_TASK_STACK_SIZE               0x1000
#define I2C_TASK_DURATION_MS              500
#define I2C_TASK_PRIO                     (osPriority_t)(17)

#define UART_BAUDRATE                      115200
#define UART_DATA_BITS                     3
#define UART_STOP_BITS                     1
#define UART_PARITY_BIT                    0
#define UART_TRANSFER_SIZE                 20

#define UART_TASK_STACK_SIZE               0x1000
#define UART_TASK_PRIO                     (osPriority_t)(17)

#define ADC_TASK_STACK_SIZE 0x1000
#define ADC_TASK_PRIO (osPriority_t)(17)
#define ADC_AUTO_SAMPLE_TEST_TIMES 1000

#define VREF 3300.0f // 参考电压（mV）

char send_data[100]={0};
char ligBuffer[10]={0};
char humidity[10] = {0};
char temperature[10] = {0};
char perLD[10]={0};
bool gatherFlag = true;

static uint8_t g_app_uart_rx_buff[UART_TRANSFER_SIZE] = { 0 };
char buff_out[UART_TRANSFER_SIZE]={0};

#define SLE_GATEWAY_SERVER_DELAY_COUNT         5

#define SLE_GATEWAY_TASK_STACK_SIZE            0x1200
#define SLE_ADV_HANDLE_DEFAULT              1
#define SLE_GATEWAY_SERVER_MSG_QUEUE_LEN       5
#define SLE_GATEWAY_SERVER_MSG_QUEUE_MAX_SIZE  32
#define SLE_GATEWAY_SERVER_QUEUE_DELAY         0xFFFFFFFF
#define SLE_GATEWAY_SERVER_BUFF_MAX_SIZE       800
#ifdef CONFIG_SAMPLE_SUPPORT_PERFORMANCE_TYPE
#define SLE_GATEWAY_SERVER_SEND_BUFF_MAX_LEN   250
#else
#define SLE_GATEWAY_SERVER_SEND_BUFF_MAX_LEN   40
#endif
unsigned long g_sle_uart_server_msgqueue_id;
#define SLE_GATEWAY_SERVER_LOG                 "[sle uart server]"
static void ssaps_server_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para,
    errcode_t status)
{
    osal_printk("%s ssaps read request cbk callback server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",
        SLE_GATEWAY_SERVER_LOG, server_id, conn_id, read_cb_para->handle, status);
}
static void ssaps_server_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para,
    errcode_t status)
{
    // osal_printk("%s ssaps write request callback cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",
        // SLE_GATEWAY_SERVER_LOG, server_id, conn_id, write_cb_para->handle, status);
    if ((write_cb_para->length > 0) && write_cb_para->value) {
        if (write_cb_para->value[1]== 'o') {
            ledFlag = true;
            osal_printk("正常\r\n");
        } else if (write_cb_para->value[1]== 'c') {
            ledFlag = false;
            osal_printk("警报\r\n");
        }
        else
            osal_printk("未能解析的命令\r\n");
        uapi_uart_write(CONFIG_SLE_GATEWAY_BUS, (uint8_t *)write_cb_para->value, write_cb_para->length, 0);
    }
}


static void sle_uart_server_create_msgqueue(void)
{
    if (osal_msg_queue_create("sle_uart_server_msgqueue", SLE_GATEWAY_SERVER_MSG_QUEUE_LEN, \
        (unsigned long *)&g_sle_uart_server_msgqueue_id, 0, SLE_GATEWAY_SERVER_MSG_QUEUE_MAX_SIZE) != OSAL_SUCCESS) {
        osal_printk("^%s sle_uart_server_create_msgqueue message queue create failed!\n", SLE_GATEWAY_SERVER_LOG);
    }
}

static void sle_uart_server_delete_msgqueue(void)
{
    osal_msg_queue_delete(g_sle_uart_server_msgqueue_id);
}

static void sle_uart_server_write_msgqueue(uint8_t *buffer_addr, uint16_t buffer_size)
{
    osal_msg_queue_write_copy(g_sle_uart_server_msgqueue_id, (void *)buffer_addr, \
                              (uint32_t)buffer_size, 0);
}

static int32_t sle_uart_server_receive_msgqueue(uint8_t *buffer_addr, uint32_t *buffer_size)
{
    return osal_msg_queue_read_copy(g_sle_uart_server_msgqueue_id, (void *)buffer_addr, \
                                    buffer_size, SLE_GATEWAY_SERVER_QUEUE_DELAY);
}
static void sle_uart_server_rx_buf_init(uint8_t *buffer_addr, uint32_t *buffer_size)
{
    *buffer_size = SLE_GATEWAY_SERVER_MSG_QUEUE_MAX_SIZE;
    (void)memset_s(buffer_addr, *buffer_size, 0, *buffer_size);
}
static uart_buffer_config_t g_app_uart_buffer_config = {
    .rx_buffer = g_app_uart_rx_buff,
    .rx_buffer_size = UART_TRANSFER_SIZE
};

static void app_uart_init(void)
{
    uapi_pin_set_mode(CONFIG_UART_TXD_PIN, PIN_MODE_1);
    uapi_pin_set_mode(CONFIG_UART_RXD_PIN, PIN_MODE_1);

    uart_attr_t attr = {
        .baud_rate = UART_BAUDRATE,
        .data_bits = UART_DATA_BITS,
        .stop_bits = UART_STOP_BITS,
        .parity = UART_PARITY_BIT
    };

    uart_pin_config_t pin_config = {
        .tx_pin = CONFIG_UART_TXD_PIN,
        .rx_pin = CONFIG_UART_RXD_PIN,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE
    };
    uapi_uart_deinit(CONFIG_UART_BUS_ID); 
    uapi_uart_init(CONFIG_UART_BUS_ID, &pin_config, &attr, NULL, &g_app_uart_buffer_config);

}
static void app_uart_read_int_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);
    if (buffer == NULL || length == 0) {
        osal_printk("uart%d int mode 传输非法数据!\r\n", CONFIG_UART_BUS_ID);
        return;
    }

    uint8_t *buff = (uint8_t *)buffer;
    if (memcpy_s(g_app_uart_rx_buff, length, buff, length) != EOK) {
        osal_printk("uart%d int mode 数据拷贝失败!\r\n", CONFIG_UART_BUS_ID);
        return;
    }
    memcpy(buff_out, buff, length);  // 将接收到的数据拷贝到 buff_out
    buff_out[length] = '\0';         // 确保字符串以 null 结尾

    // 检查数据是否以 \r\n 结尾
    if (length >= 2 && buff_out[length - 2] == '\r' && buff_out[length - 1] == '\n') {
        // 去掉换行符
        buff_out[length - 2] = '\0';
    }

    // // 打印接收到的原始数据
    // osal_printk("Received raw data: ");
    // for (uint16_t i = 0; i < length; i++) {
    //     osal_printk("%c", buff[i]);
    // }
    // osal_printk("\r\n");

    // 尝试解析数据
    int valueLD;
    char *rangeStr = strstr(buff_out, "Range");
    if (rangeStr != NULL) {
        // 跳过 "Range" 字符串
        rangeStr += 5;  // "Range" 的长度是 5
        // 跳过空白字符
        while (isspace((unsigned char)*rangeStr)) {
            rangeStr++;
        }
        // 提取数值
        if (sscanf(rangeStr, "%d", &valueLD) == 1) {
            sprintf(perLD, "%s", rangeStr);
        } else {
            osal_printk("无法解析 'Range' 后面的数字.\r\n");
        }
    } else {
        osal_printk("在接收的数据中未找到 'Range'\r\n");
    }
}
#define DEBOUNCE_TIME_MS 50  // 防抖时间，单位为毫秒

static void gpio_callback_func(pin_t pin, uintptr_t param)
{
    UNUSED(pin);
    UNUSED(param);

    // 延迟一段时间后再次确认按钮状态
    osDelay(DEBOUNCE_TIME_MS);

    // 再次检查按钮状态
    if (uapi_gpio_get_val(CONFIG_BUTTON_PIN) == GPIO_LEVEL_LOW)  // 假设按钮按下为低电平
    {
            gatherFlag=!gatherFlag;
            // osal_printk("切换页面：%d\r\n",showFlag);
    }
}

static void button_entry(void)
{
    uapi_pin_set_mode(CONFIG_BUTTON_PIN, HAL_PIO_FUNC_GPIO);
    uapi_pin_set_pull(CONFIG_BUTTON_PIN, PIN_PULL_TYPE_UP);
    uapi_gpio_set_dir(CONFIG_BUTTON_PIN, GPIO_DIRECTION_INPUT);    
    uapi_gpio_register_isr_func(CONFIG_BUTTON_PIN, GPIO_INTERRUPT_DEDGE, gpio_callback_func);
}

void test_adc_callback(uint8_t ch, uint32_t *buffer, uint32_t length, bool *next)
{
    UNUSED(next);
    for (uint32_t i = 0; i < length; i++)
    {
        float voltage_mv = buffer[i]; // 获取电压值（单位：mV）

        float lux = (VREF - voltage_mv) / 33.0f;

        // 限制Lux值范围
        if (lux > 1000.0f)
        {
            lux = 1000.0f;
        }
        else if(lux<0.0f)
            lux=0.0f;
        
        sprintf(ligBuffer, "%.2f", lux);
        
    }
}
//采集
static void *gather_task(const char *arg)  
{
    UNUSED(arg);
    osal_printk("start adc sample test");

    float temp = 0.0f;
    float humi = 0.0f;
    //开启sht3x
    sht30_Port_Init();

    uapi_adc_init(ADC_CLOCK_500KHZ);
    uapi_adc_power_en(AFE_SCAN_MODE_MAX_NUM, true);
    adc_scan_config_t config = {
        .type = 0,
        .freq = 1,
    };

    app_uart_init();
    osal_printk("uart%d int mode register receive callback start!\r\n", CONFIG_UART_BUS_ID);
    if (uapi_uart_register_rx_callback(CONFIG_UART_BUS_ID, UART_RX_CONDITION_FULL_OR_IDLE,
                                       16, app_uart_read_int_handler) == ERRCODE_SUCC) {
        osal_printk("uart%d int mode register receive callback succ!\r\n", CONFIG_UART_BUS_ID);
    }
    

    while (1)
    {
        if(gatherFlag){
            
            uapi_adc_auto_scan_ch_enable(ADC_CHANNEL_2, config, test_adc_callback);
            uapi_adc_auto_scan_ch_disable(ADC_CHANNEL_2);

            // 发送开始测量命令
            sht30_start_measurement();
            if (sht30_read_data(&temp, &humi) == 0){
                sprintf(temperature, "%.2f", temp);
                sprintf(humidity, "%.2f", humi);
                // #ifdef CONFIG_RAN_LED
                //     if(temp>CONFIG_LED_TEM_NUM)
                //         ledFlagRad=true;
                //     else
                //         ledFlagRad=false;
                // #endif
            }else {
                osal_printk("error");
                osDelay(200);
            }
            
        }
        else{
           
        }
        osal_printk("A running\r\n");
        osal_printk("雷达：%s\r\n", perLD);
        osal_printk("湿度: %s\r\n", humidity);
        osal_printk("温度: %s\r\n", temperature);
        osal_printk("光照：%s\r\n", ligBuffer);
        osal_printk("GPS:%s\r\n",gngga);
        osal_printk("%s\r\n",CONFIG_STU_NAME);
        osal_printk("%s\r\n",CONFIG_STU_NUM);
        osal_printk("\r\n");
        osal_printk("\r\n");
        snprintf(send_data, sizeof(send_data), "1,Hum:%s,Tem:%s,Lig:%s,Radar:%s,GPS:%s", humidity, temperature, ligBuffer,perLD,gngga);
        if (sle_uart_client_is_connected()) {
            sle_uart_server_send_report_by_handle((const uint8_t *)send_data, strlen(send_data));
        } else {
            // osal_printk("%s 星闪 client 未连接! \r\n", SLE_GATEWAY_SERVER_LOG);
        }
        
        osal_msleep(2000);
    }

    return NULL;
}

static void gather_entry(void)
{
    osThreadAttr_t attr;

    attr.name = "ADCTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = ADC_TASK_STACK_SIZE;
    attr.priority = ADC_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)gather_task, NULL, &attr) == NULL)
    {
        osal_printk("Failed to create ADC task.\n");
    }
}


static void *sle_uart_server_task(const char *arg)
{
    unused(arg);
    uint8_t rx_buf[SLE_GATEWAY_SERVER_MSG_QUEUE_MAX_SIZE] = {0};
    uint32_t rx_length = SLE_GATEWAY_SERVER_MSG_QUEUE_MAX_SIZE;
    uint8_t sle_connect_state[] = "sle_dis_connect";

    sle_uart_server_create_msgqueue();
    sle_uart_server_register_msg(sle_uart_server_write_msgqueue);
    sle_uart_server_init(ssaps_server_read_request_cbk, ssaps_server_write_request_cbk);

    int ret;
    while (1) {
        sle_uart_server_rx_buf_init(rx_buf, &rx_length);
        sle_uart_server_receive_msgqueue(rx_buf, &rx_length);
        if (strncmp((const char *)rx_buf, (const char *)sle_connect_state, sizeof(sle_connect_state)) == 0) {
            ret = sle_start_announce(SLE_ADV_HANDLE_DEFAULT);
            if (ret != ERRCODE_SLE_SUCCESS) {
                osal_printk("%s sle_connect_state_changed_cbk,sle_start_announce fail :%02x\r\n",
                    SLE_GATEWAY_SERVER_LOG, ret);
            }
        }
        osal_msleep(SLE_GATEWAY_TASK_DURATION_MS);

        
    }
    sle_uart_server_delete_msgqueue();
    return NULL;
}


static void sle_uart_entry(void)
{
    osal_task *task_handle = NULL;
    osal_kthread_lock();
    task_handle = osal_kthread_create((osal_kthread_handler)sle_uart_server_task, 0, "SLEUartServerTask",
                                      SLE_GATEWAY_TASK_STACK_SIZE);
    if (task_handle != NULL) {
        osal_kthread_set_priority(task_handle, SLE_GATEWAY_TASK_PRIO);
    }
    osal_kthread_unlock();
}


app_run(gather_entry);
app_run(button_entry);
app_run(sle_uart_entry);
app_run(GPS_gather_entry);